package com.djmw.mouse.entity;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import com.djmw.mouse.service.constants.Constants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@Entity
@Table(name = "t_cv_lang")
public class CvLang extends IdEntity {
    public static final int LANG_CHINESE = 0;
    public static final int LANG_ENGLISH = 1;
    public static final String[] NAMES = { "中文", "英文" };

    private Cv cv;
    private Integer lang;
    private int expectedJobType;
    private int expectedLocation;
    private int expectedIndustry;
    private int expectedPositionType;
    private int expectedSalaryRange;
    private int expectedOnboard;
    private String selfComment;
    private int englishLevel;
    private int japaneseLevel;
    private int toefl;
    private int gre;
    private int gmat;
    private double ielts;
    private double toeic;

    private List<CvEducation> cvEducation;
    private List<CvWorkingExperience> cvWorkingExperience;

    private Set<Application> application = new HashSet<Application>(0);

    public CvLang() {
    }

    public CvLang(Cv cv, int lang) {
        this.cv = cv;
        this.lang = lang;
    }

    @ManyToOne
    @JoinColumn(name = "c_cv_id")
    public Cv getCv() {
        return cv;
    }

    public void setCv(Cv cv) {
        this.cv = cv;
    }

    @Column(name = "c_lang")
    public Integer getLang() {
        return lang;
    }

    public void setLang(Integer lang) {
        this.lang = lang;
    }

    @Column(name = "c_job_type")
    public int getExpectedJobType() {
        return expectedJobType;
    }

    public void setExpectedJobType(int expectedJobType) {
        this.expectedJobType = expectedJobType;
    }

    @Column(name = "c_location")
    public int getExpectedLocation() {
        return expectedLocation;
    }

    public void setExpectedLocation(int expectedLocation) {
        this.expectedLocation = expectedLocation;
    }

    @Column(name = "c_industry")
    public int getExpectedIndustry() {
        return expectedIndustry;
    }

    public void setExpectedIndustry(int expectedIndustry) {
        this.expectedIndustry = expectedIndustry;
    }

    @Column(name = "c_position_type")
    public int getExpectedPositionType() {
        return expectedPositionType;
    }

    public void setExpectedPositionType(int expectedPositionType) {
        this.expectedPositionType = expectedPositionType;
    }

    @Column(name = "c_salary_range")
    public int getExpectedSalaryRange() {
        return expectedSalaryRange;
    }

    public void setExpectedSalaryRange(int expectedSalaryRange) {
        this.expectedSalaryRange = expectedSalaryRange;
    }

    @Column(name = "c_onboard")
    public int getExpectedOnboard() {
        return expectedOnboard;
    }

    public void setExpectedOnboard(int expectedOnboard) {
        this.expectedOnboard = expectedOnboard;
    }

    @Column(name = "c_self_comment")
    public String getSelfComment() {
        return selfComment;
    }

    public void setSelfComment(String selfComment) {
        this.selfComment = selfComment;
    }

    @Column(name = "c_english_level")
    public int getEnglishLevel() {
        return englishLevel;
    }

    public void setEnglishLevel(int englishLevel) {
        this.englishLevel = englishLevel;
    }

    @Column(name = "c_japanese_level")
    public int getJapaneseLevel() {
        return japaneseLevel;
    }

    public void setJapaneseLevel(int japaneseLevel) {
        this.japaneseLevel = japaneseLevel;
    }

    @Column(name = "c_toefl")
    public int getToefl() {
        return toefl;
    }

    public void setToefl(int toefl) {
        this.toefl = toefl;
    }

    @Column(name = "c_gre")
    public int getGre() {
        return gre;
    }

    public void setGre(int gre) {
        this.gre = gre;
    }

    @Column(name = "c_gmat")
    public int getGmat() {
        return gmat;
    }

    public void setGmat(int gmat) {
        this.gmat = gmat;
    }

    @Column(name = "c_ielts")
    public double getIelts() {
        return ielts;
    }
    public void setIelts(double ielts) {
        this.ielts = ielts;
    }

    @Column(name = "c_toeic")
    public double getToeic() {
        return toeic;
    }
    public void setToeic(double toeic) {
        this.toeic = toeic;
    }

    @Transient
    public String getName() {
        return NAMES[lang];
    }

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cvLang")
    @OrderBy("order ASC")
    public List<CvEducation> getCvEducation() {
        return cvEducation;
    }
    public void setCvEducation(List<CvEducation> cvEducation) {
        this.cvEducation = cvEducation;
    }

    @Transient
    public String getEducationJson() {
        return getElementJson(cvEducation);
    }

    @Transient
    public String getDegreeName() {
        if (cvEducation == null || cvEducation.size() == 0) {
            return "";
        }
        int maxDegree = 0;
        for (int i = 0; i < cvEducation.size(); i++) {
            Integer degree = cvEducation.get(i).getDegree();
            if (degree != null && degree > maxDegree) {
                maxDegree = degree;
            }
        }
        return maxDegree == 0 ? "" : Constants.EDUCATIONS.get(maxDegree).getName();
    }

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "cvLang")
    @OrderBy("order ASC")
    public List<CvWorkingExperience> getCvWorkingExperience() {
        return cvWorkingExperience;
    }
    public void setCvWorkingExperience(List<CvWorkingExperience> cvWorkingExperience) {
        this.cvWorkingExperience = cvWorkingExperience;
    }

    @Transient
    public String getWorkingExperienceJson() {
        return getElementJson(cvWorkingExperience);
    }

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "pk.cvLang")
    public Set<Application> getApplication() {
        return application;
    }
    public void setApplication(Set<Application> application) {
        this.application = application;
    }

    @Transient
    public String getElementJson(Object element) {
        if (element == null) {
            return "[]";
        }
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.writeValueAsString(element);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return "[]";
        }
    }

    public void normalize() {
        if (getCvEducation() != null) {
            for (CvEducation cve : getCvEducation()) {
                if (cve.getCvLang() == null) {
                    cve.setCvLang(this);
                }
            }
        }
        if (getCvWorkingExperience() != null) {
            for (CvWorkingExperience cvw : getCvWorkingExperience()) {
                if (cvw.getCvLang() == null) {
                    cvw.setCvLang(this);
                }
            }
        }
    }
}
